package com.tencent.tic.core.impl;

import android.content.Context;

import com.tencent.imsdk.TIMCallBack;
import com.tencent.imsdk.TIMGroupAddOpt;
import com.tencent.imsdk.TIMGroupManager;
import com.tencent.imsdk.TIMLogLevel;
import com.tencent.imsdk.TIMManager;
import com.tencent.imsdk.TIMSdkConfig;
import com.tencent.imsdk.TIMValueCallBack;
import com.tencent.teduboard.TEduBoardController;
import com.tencent.tic.core.TICClassroomOption;
import com.tencent.tic.core.TICManager;
import com.tencent.tic.core.impl.observer.TICIMStatusObservable;
import com.tencent.tic.core.impl.utils.CallbackUtil;

import java.util.List;

public class TICManagerImpl extends TICManager {

    private static final String TAG = "TICManager";
    TICCallback mEnterRoomCallback; // 进房callback
    int mDisableModule = TICDisableModule.TIC_DISABLE_MODULE_NONE;
    //Board
    private TEduBoardController mBoard;
    private BoardCallback mBoardCallback;

    private static final byte[] SYNC = new byte[1];

    private Context mAppContext;
    private int sdkAppId = 0;
    private UserInfo userInfo;
    private TICClassroomOption classroomOption;

    private TICIMStatusObservable mStatusListner;

    /////////////////////////////////////////////////////////////////////////////////
//
//                      （一）初始和终止接口函数
//
/////////////////////////////////////////////////////////////////////////////////
    private static volatile TICManager instance;

    public static TICManager sharedInstance() {
        if (instance == null) {
            synchronized (SYNC) {
                if (instance == null) {
                    instance = new TICManagerImpl();
                }
            }
        }
        return instance;
    }

    private TICManagerImpl() {
        userInfo = new UserInfo();
        mStatusListner = new TICIMStatusObservable();
    }

    @Override
    public int init(Context context, int appId) {
        int result = init(context, appId, mDisableModule);
        return result;
    }


    public int init(Context context, int appId, int disableModule) {
        TICReporter.updateAppId(appId);
        TICReporter.report(TICReporter.EventId.INIT_SDK_START);

        //0、给值
        sdkAppId = appId;
        mAppContext = context.getApplicationContext();

        //1、 TIM SDK初始化
        TIMSdkConfig timSdkConfig = new TIMSdkConfig(appId)
                .enableLogPrint(true)
                .setLogLevel(TIMLogLevel.DEBUG); //TODO::在正式发布时，设置TIMLogLevel.OFF
        TIMManager.getInstance().init(context, timSdkConfig);
      
        //2. TEdu Board
        if (mBoard == null) {
            mBoard = new TEduBoardController(mAppContext);
            mBoardCallback = new BoardCallback();
            mBoard.addCallback(mBoardCallback);
        }
       
        TICReporter.report(TICReporter.EventId.INIT_SDK_END);
        return 0;
    }

    @Override
    public int unInit() {

        return 0;
    }
   

    public TEduBoardController getBoardController() {
        if (mBoard == null) {
        }
        return mBoard;
    }

    @Override
    public void addIMStatusListener(TICIMStatusListener callback) {
        mStatusListner.addObserver(callback);
    }

    @Override
    public void removeIMStatusListener(TICIMStatusListener callback) {
        mStatusListner.removeObserver(callback);
    }

    /////////////////////////////////////////////////////////////////////////////////
    //
    //                      （二）TIC登录/登出/创建销毁课堂/进入退出课堂接口函数
    //
    /////////////////////////////////////////////////////////////////////////////////
    @Override
    public void login(final String userId, final String userSig, final TICCallback callBack) {

        TICReporter.updateRoomId(0);
        TICReporter.updateUserId(userId);
        TICReporter.report(TICReporter.EventId.LOGIN_START);
        // IM 登陆
        setUserInfo(userId, userSig);

        TIMManager.getInstance().login(userId, userSig, new TIMCallBack() {
            @Override
            public void onSuccess() {
                TICReporter.report(TICReporter.EventId.LOGIN_END);
                //成功登录后，加入消息和状态监听
                TIMManager.getInstance().getUserConfig().setUserStatusListener(mStatusListner);
                if (null != callBack) {
                    callBack.onSuccess("");
                }
            }

            @Override
            public void onError(int errCode, String errMsg) {
                TICReporter.report(TICReporter.EventId.LOGIN_END, errCode, errMsg);
                if (null != callBack) {
                    callBack.onError(MODULE_IMSDK, errCode, "login failed: " + errMsg);
                }
            }
        });
    }

    @Override
    public void logout(final TICCallback callback) {
        TICReporter.report(TICReporter.EventId.LOGOUT_START);
        TIMManager.getInstance().logout(new TIMCallBack() {
            @Override
            public void onSuccess() {
                TICReporter.report(TICReporter.EventId.LOGOUT_END);
                if (null != callback) {
                    callback.onSuccess("");
                }
            }

            @Override
            public void onError(int errCode, String errMsg) {
                TICReporter.report(TICReporter.EventId.LOGOUT_END, errCode, errMsg);
                if (null != callback) {
                    callback.onError(MODULE_IMSDK, errCode, "logout failed: " + errMsg);
                }
            }
        });

        //退出登录后，去掉消息的监听
        TIMManager.getInstance().getUserConfig().setUserStatusListener(null);
        TIMManager.getInstance().getUserConfig().setGroupEventListener(null);
    }

    @Override
    public void createClassroom(final int classId, final int scene, final TICCallback callback) {
        TICReporter.report(TICReporter.EventId.CREATE_GROUP_START);
        // 为了减少用户操作成本（收到群进出等通知需要配置工单才生效）群组类型由ChatRoom改为Public
        final String groupId = String.valueOf(classId);
        final String groupName = "interact group";
        final String groupType = ((scene == TICManager.TICClassScene.TIC_CLASS_SCENE_LIVE) ? "AVChatRoom" : "Public");

        TIMGroupManager.CreateGroupParam param = new TIMGroupManager.CreateGroupParam(groupType, groupName);
        param.setGroupId(groupId);
        param.setAddOption(TIMGroupAddOpt.TIM_GROUP_ADD_ANY); //
        TIMGroupManager.getInstance().createGroup(param, new TIMValueCallBack<String>() {

            @Override
            public void onSuccess(String s) {
                TICReporter.report(TICReporter.EventId.CREATE_GROUP_END);
                if (null != callback) {
                    callback.onSuccess(classId);
                }
            }

            @Override
            public void onError(int errCode, String errMsg) {
                if (null != callback) {
                    if (errCode == 10025) { // 群组ID已被使用，并且操作者为群主，可以直接使用。
                        callback.onSuccess(classId);
                    } else {
                        TICReporter.report(TICReporter.EventId.CREATE_GROUP_END, errCode, errMsg);
                        callback.onError(MODULE_IMSDK, errCode, errMsg);
                    }
                }
            }
        });
    }

    @Override
    public void destroyClassroom(final int classId, final TICCallback callback) {

        TICReporter.report(TICReporter.EventId.DELETE_GROUP_START);
        final String groupId = String.valueOf(classId);

        TIMGroupManager.getInstance().deleteGroup(groupId, new TIMCallBack() {
            @Override
            public void onError(int errorCode, String errInfo) {
                TICReporter.report(TICReporter.EventId.DELETE_GROUP_END, errorCode, errInfo);
                CallbackUtil.notifyError(callback, MODULE_IMSDK, errorCode, errInfo);
            }

            @Override
            public void onSuccess() {
                TICReporter.report(TICReporter.EventId.DELETE_GROUP_END);

            }
        });

    }

    @Override
    public void joinClassroom(final TICClassroomOption option, final TICCallback callback) {

        if (option == null || option.getClassId() < 0) {
            CallbackUtil.notifyError(callback, MODULE_TIC_SDK, Error.ERR_INVALID_PARAMS, Error.ERR_MSG_INVALID_PARAMS);
            return;
        }

        classroomOption = option;

        final int classId = classroomOption.getClassId();
        String groupId = String.valueOf(classId);
        final String desc = "board group";

        TICReporter.updateRoomId(classId);
        TICReporter.report(TICReporter.EventId.JOIN_GROUP_START);
        TIMGroupManager.getInstance().applyJoinGroup(groupId, desc + groupId, new TIMCallBack() {
            @Override
            public void onSuccess() {

                TICReporter.report(TICReporter.EventId.JOIN_GROUP_END);
                onJoinClassroomSuccessfully(callback);
            }

            @Override
            public void onError(int errCode, String errMsg) {
                if (callback != null) {
                    if (errCode == 10013) { //you are already group member.
                        TICReporter.report(TICReporter.EventId.JOIN_GROUP_END);
                        onJoinClassroomSuccessfully(callback);
                    } else {
                        TICReporter.report(TICReporter.EventId.JOIN_GROUP_END, errCode, errMsg);
                        callback.onError(MODULE_IMSDK, errCode, errMsg);
                    }
                }
            }
        });
    }

    @Override
    public void quitClassroom(boolean clearBoard, final TICCallback callback) {

        if (classroomOption == null) {
            CallbackUtil.notifyError(callback, MODULE_TIC_SDK, Error.ERR_NOT_IN_CLASS, Error.ERR_MSG_NOT_IN_CLASS);
            return;
        }

        TICReporter.report(TICReporter.EventId.QUIT_GROUP_START);
       
        //2、如果clearBoard= true, 清除board中所有的历史数据，下次进来时看到的都是全新白板
        unitTEduBoard(clearBoard);

        //3、im退房间
        int classId = classroomOption.getClassId();
        String groupId = String.valueOf(classId);
        TIMGroupManager.getInstance().quitGroup(groupId, new TIMCallBack() {//NOTE:在被挤下线时，不会回调
            @Override
            public void onError(int errorCode, String errInfo) {
                TICReporter.report(TICReporter.EventId.QUIT_GROUP_END, errorCode, errInfo);
                if (callback != null) {
                    if (errorCode == 10009) {
                        callback.onSuccess(0);
                    } else {
                        callback.onError(MODULE_IMSDK, errorCode, errInfo);
                    }
                }
            }

            @Override
            public void onSuccess() {
                TICReporter.report(TICReporter.EventId.QUIT_GROUP_END);
                CallbackUtil.notifySuccess(callback, 0);
            }
        });
        releaseClass();
    }

    private void onJoinClassroomSuccessfully(final TICCallback callback) {
        if (classroomOption == null || classroomOption.getClassId() < 0) {
            CallbackUtil.notifyError(callback, MODULE_TIC_SDK, Error.ERR_INVALID_PARAMS, Error.ERR_MSG_INVALID_PARAMS);
            return;
        }
        mEnterRoomCallback = callback;
        if (mEnterRoomCallback != null) {
            mEnterRoomCallback.onSuccess("succ");
        }
        //Board进行初始化
        initTEduBoard();
    }

    private void initTEduBoard() {
        //生成一个继承于TEduBoardController.TEduBoardCallback事件监听，交给白板对象，用于处理白板事件响应。
        if (classroomOption != null) {
            if (classroomOption.boardCallback != null) {
                mBoard.addCallback(classroomOption.boardCallback);
            }
        }
        TICReporter.report(TICReporter.EventId.INIT_BOARD_START);
        //调用初始化函数
        TEduBoardController.TEduBoardAuthParam authParam = new TEduBoardController.TEduBoardAuthParam(sdkAppId
                , userInfo.getUserId(), userInfo.getUserSig());
        mBoard.init(authParam, classroomOption.getClassId(), classroomOption.boardInitPara);
    }

    private void unitTEduBoard(boolean clearBoard) {
        if (mBoard != null) {
            if (classroomOption != null && classroomOption.boardCallback != null) {
                mBoard.removeCallback(classroomOption.boardCallback);
            }

            if (clearBoard) {
                mBoard.reset();
            }

            TICReporter.report(TICReporter.EventId.UN_INIT_BOARD);
            mBoard.uninit();
        }
    }

    private void releaseClass() {
        classroomOption = null;
    }


    public void setUserInfo(final String userId, final String userSig) {
        userInfo.setUserInfo(userId, userSig);
    }

    //白板回调，用于监控事件
    static class BoardCallback implements TEduBoardController.TEduBoardCallback {

        @Override
        public void onTEBError(int code, String msg) {
            TICReporter.report(TICReporter.EventId.ON_TEBERROR, code, msg);
        }

        @Override
        public void onTEBWarning(int code, String msg) {
            TICReporter.report(TICReporter.EventId.ON_TEBWARNING, code, msg);
        }

        @Override
        public void onTEBInit() {
            TICReporter.report(TICReporter.EventId.INIT_BOARD_END);
        }

        @Override
        public void onTEBHistroyDataSyncCompleted() {
            TICReporter.report(TICReporter.EventId.SYNC_BOARD_HISTORY_END);
        }

        @Override
        public void onTEBSyncData(String s) {

        }

        @Override
        public void onTEBUndoStatusChanged(boolean b) {

        }

        @Override
        public void onTEBRedoStatusChanged(boolean b) {

        }

        @Override
        public void onTEBImageStatusChanged(String s, String s1, int i) {

        }

        @Override
        public void onTEBSetBackgroundImage(String s) {

        }

        @Override
        public void onTEBBackgroundH5StatusChanged(String s, String s1, int i) {

        }

        @Override
        public void onTEBTextElementWarning(String code, String message) {
            
        }

        @Override
        public void onTEBImageElementStatusChanged(int status, String currentBoardId, String imgUrl, String currentImgUrl) {

        }

        @Override
        public void onTEBAddBoard(List<String> list, String s) {

        }

        @Override
        public void onTEBDeleteBoard(List<String> list, String s) {

        }

        @Override
        public void onTEBGotoBoard(String s, String s1) {

        }

        @Override
        public void onTEBGotoStep(int currentStep, int total) {

        }

        @Override
        public void onTEBRectSelected() {

        }

        @Override
        public void onTEBRefresh() {

        }

        @Override
        public void onTEBOfflineWarning(int count) {
            
        }

        @Override
        public void onTEBSnapshot(String path, int code, String msg) {

        }

        @Override
        public void onTEBH5PPTStatusChanged(int statusCode, String fid, String describeMsg) {

        }

        @Override
        public void onTEBTextElementStatusChange(String status, String id, String value, int left, int top) {
            
        }


        @Override
        public void onTEBAddTranscodeFile(String s) {
        }

        @Override
        public void onTEBDeleteFile(String s) {

        }

        @Override
        public void onTEBSwitchFile(String s) {

        }

        @Override
        public void onTEBFileUploadProgress(String s, int i, int i1, int i2, float v) {

        }

        @Override
        public void onTEBFileUploadStatus(String s, int i, int i1, String s1) {

        }

        @Override
        public void onTEBFileTranscodeProgress(String s, String s1, String s2, TEduBoardController.TEduBoardTranscodeFileResult tEduBoardTranscodeFileResult) {

        }

        @Override
        public void onTEBH5FileStatusChanged(String fileId, int status) {

        }

        @Override
        public void onTEBAddImagesFile(String fileId) {

        }

        @Override
        public void onTEBVideoStatusChanged(String fileId, int status, float progress, float duration) {

        }

        @Override
        public void onTEBAudioStatusChanged(String elementId, int status, float progress, float duration) {
            
        }

        @Override
        public void onTEBAddImageElement(String url) {

        }

        @Override
        public void onTEBAddElement(String id,int type, String url) {
            
        }

        @Override
        public void onTEBDeleteElement(List<String> id) {
            
        }

        @Override
        public void onTEBSelectElement(List<TEduBoardController.ElementItem> elementItemList) {
            
        }

        @Override
        public void onTEBMathGraphEvent(int code, String boardId, String graphId, String message) {

        }

        @Override
        public void onTEBZoomDragStatus(String fid, int scale, int xOffset, int yOffset) {

        }

    }
}
